//! Appender 模块
//!
//! 提供日志输出目标的统一接口和实现。
//!
//! # 概述
//!
//! Appender 是 log4r 中负责将日志事件写入目标的组件。
//! 所有 Appender 实现必须是线程安全的 (`Send + Sync`)，
//! 以支持多线程环境下的并发日志写入。
//!
//! # 子模块
//!
//! - [`console`] - 控制台输出（stdout/stderr）
//! - [`mod@file`] - 文件输出
//! - [`syslog`] - 系统日志输出（跨平台）
//!
//! # 生命周期管理
//!
//! Appender 的生命周期由日志系统管理，遵循以下阶段：
//!
//! 1. **创建**: 通过各 Appender 的构造函数创建实例
//! 2. **使用**: 通过 [`Appender::write`] 方法写入日志事件
//! 3. **刷新**: 通过 [`Appender::flush`] 方法确保缓冲数据写入目标
//! 4. **关闭**: 通过 [`Appender::close`] 方法释放资源
//!
//! # 实现者注意事项
//!
//! 实现 [`Appender`] trait 时需要注意：
//!
//! - 所有方法都必须是线程安全的
//! - `write` 方法不应该阻塞太长时间
//! - `close` 方法应该确保所有数据都已写入
//! - 错误应该通过 `Result` 返回，禁止使用 panic
//!
//! # 示例
//!
//! ```rust
//! use log4r::appender::Appender;
//! use log4r::{LogEvent, Level, Log4rError};
//!
//! // 使用 Appender trait object 写入日志
//! fn write_log(appender: &dyn Appender, event: &LogEvent) -> Result<(), Log4rError> {
//!     appender.write(event)?;
//!     appender.flush()?;
//!     Ok(())
//! }
//!
//! // 使用 Box<dyn Appender> 管理多个 Appender
//! fn manage_appenders(appenders: Vec<Box<dyn Appender>>, event: &LogEvent) {
//!     for appender in &appenders {
//!         if let Err(e) = appender.write(event) {
//!             eprintln!("写入日志失败: {}", e);
//!         }
//!     }
//! }
//! ```

pub mod console;
pub mod file;
pub mod rotation;
pub mod syslog;

// 重导出 console 模块的公共类型
pub use console::{ConsoleAppender, ConsoleTarget};

// 重导出 file 模块的公共类型
pub use file::FileAppender;

// 重导出 rotation 模块的公共类型
pub use rotation::RotatingFileAppender;

use crate::error::Log4rError;
use crate::event::LogEvent;

/// 日志输出目标的统一接口
///
/// 所有 Appender 实现必须是线程安全的 (`Send + Sync`)，
/// 以支持多线程环境下的日志写入。
///
/// # 方法
///
/// - [`write`](Appender::write): 写入单条日志事件
/// - [`flush`](Appender::flush): 刷新内部缓冲区
/// - [`close`](Appender::close): 关闭 Appender 并释放资源
///
/// # 生命周期
///
/// ```text
/// ┌─────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
/// │  创建   │ ──▶ │  写入   │ ──▶ │  刷新   │ ──▶ │  关闭   │
/// │  new()  │     │ write() │     │ flush() │     │ close() │
/// └─────────┘     └────┬────┘     └─────────┘     └─────────┘
///                      │                ▲
///                      └────────────────┘
///                         (可重复调用)
/// ```
///
/// # 实现者注意事项
///
/// 1. 所有方法都应该是线程安全的
/// 2. `write` 方法不应该阻塞太长时间
/// 3. `close` 方法应该确保所有数据都已写入
/// 4. 错误应该通过 `Result` 返回，禁止使用 panic/unwrap/expect
///
/// # 示例
///
/// ```rust
/// use log4r::appender::Appender;
/// use log4r::{LogEvent, Level, Log4rError};
/// use std::sync::Mutex;
///
/// /// 简单的内存 Appender 示例
/// struct MemoryAppender {
///     events: Mutex<Vec<String>>,
/// }
///
/// impl MemoryAppender {
///     fn new() -> Self {
///         Self {
///             events: Mutex::new(Vec::new()),
///         }
///     }
/// }
///
/// impl Appender for MemoryAppender {
///     fn write(&self, event: &LogEvent) -> Result<(), Log4rError> {
///         let mut events = self.events.lock()
///             .map_err(|_| Log4rError::appender("MemoryAppender", "获取锁失败"))?;
///         events.push(format!("[{}] {}", event.level, event.message));
///         Ok(())
///     }
///
///     fn flush(&self) -> Result<(), Log4rError> {
///         // 内存 Appender 无需刷新
///         Ok(())
///     }
///
///     fn close(&self) -> Result<(), Log4rError> {
///         // 内存 Appender 无需关闭
///         Ok(())
///     }
/// }
/// ```
pub trait Appender: Send + Sync {
    /// 写入单条日志事件
    ///
    /// 将日志事件写入到输出目标。对于带缓冲的 Appender，
    /// 数据可能暂存在缓冲区中，需要调用 [`flush`](Appender::flush) 确保写入。
    ///
    /// # Arguments
    ///
    /// * `event` - 要写入的日志事件
    ///
    /// # Returns
    ///
    /// * `Ok(())` - 写入成功
    /// * `Err(Log4rError)` - 写入失败
    ///
    /// # Errors
    ///
    /// * [`Log4rError::IoError`] - I/O 操作失败
    /// * [`Log4rError::AppenderError`] - Appender 特定错误（如锁获取失败）
    ///
    /// # 示例
    ///
    /// ```rust
    /// use log4r::appender::Appender;
    /// use log4r::{LogEvent, Level};
    ///
    /// fn log_message(appender: &dyn Appender) {
    ///     let event = LogEvent::new(Level::Info, "my_app", "操作完成");
    ///     if let Err(e) = appender.write(&event) {
    ///         eprintln!("写入日志失败: {}", e);
    ///     }
    /// }
    /// ```
    fn write(&self, event: &LogEvent) -> Result<(), Log4rError>;

    /// 刷新内部缓冲区
    ///
    /// 确保所有已写入的数据都被刷新到目标。
    /// 对于无缓冲的 Appender，此方法可以是空操作。
    ///
    /// # Returns
    ///
    /// * `Ok(())` - 刷新成功
    /// * `Err(Log4rError)` - 刷新失败
    ///
    /// # Errors
    ///
    /// * [`Log4rError::IoError`] - I/O 操作失败
    /// * [`Log4rError::AppenderError`] - Appender 特定错误
    ///
    /// # 示例
    ///
    /// ```rust
    /// use log4r::appender::Appender;
    /// use log4r::{LogEvent, Level};
    ///
    /// fn write_and_flush(appender: &dyn Appender, event: &LogEvent) {
    ///     // 写入后立即刷新，确保数据持久化
    ///     appender.write(event).ok();
    ///     appender.flush().ok();
    /// }
    /// ```
    fn flush(&self) -> Result<(), Log4rError>;

    /// 关闭 Appender 并释放资源
    ///
    /// 此方法应该：
    /// 1. 刷新所有待写入的数据
    /// 2. 关闭底层资源（文件句柄、网络连接等）
    /// 3. 释放所有分配的内存
    ///
    /// 关闭后，Appender 不应该再被使用。
    ///
    /// # Returns
    ///
    /// * `Ok(())` - 关闭成功
    /// * `Err(Log4rError)` - 关闭失败
    ///
    /// # Errors
    ///
    /// * [`Log4rError::IoError`] - I/O 操作失败
    /// * [`Log4rError::AppenderError`] - Appender 特定错误
    ///
    /// # 示例
    ///
    /// ```rust
    /// use log4r::appender::Appender;
    ///
    /// fn cleanup_appender(appender: &dyn Appender) {
    ///     // 关闭前先刷新
    ///     appender.flush().ok();
    ///     if let Err(e) = appender.close() {
    ///         eprintln!("关闭 Appender 失败: {}", e);
    ///     }
    /// }
    /// ```
    fn close(&self) -> Result<(), Log4rError>;
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Mutex;

    // ========================================
    // AC-4.1.4: 编译时验证 Appender trait 是 Send + Sync
    // ========================================

    /// 编译时断言辅助函数
    fn assert_send_sync<T: Send + Sync>() {}

    /// UT-4.1-001: 验证 Appender trait 要求 Send + Sync
    #[test]
    fn test_appender_trait_requires_send_sync() {
        // GIVEN: 一个实现 Appender 的类型
        // WHEN: 检查 trait bounds
        // THEN: 编译通过即验证成功
        fn check_trait_bounds<T: Appender>() {
            assert_send_sync::<T>();
        }

        // 使用 MockAppender 验证
        check_trait_bounds::<MockAppender>();
    }

    /// UT-4.1-002: 验证 dyn Appender 可以作为 trait object
    #[test]
    fn test_appender_can_be_trait_object() {
        // GIVEN: Appender trait
        // WHEN: 尝试创建 trait object
        // THEN: 编译通过即验证成功
        fn accept_appender(_: &dyn Appender) {}
        fn accept_boxed_appender(_: Box<dyn Appender>) {}

        let mock = MockAppender::new();
        accept_appender(&mock);
        accept_boxed_appender(Box::new(mock));
    }

    /// UT-4.1-003: 验证 Box<dyn Appender> 是 Send + Sync
    #[test]
    fn test_boxed_appender_is_send_sync() {
        // GIVEN: Box<dyn Appender>
        // WHEN: 检查 Send + Sync
        // THEN: 编译通过即验证成功
        fn assert_send<T: Send>() {}
        fn assert_sync<T: Sync>() {}

        assert_send::<Box<dyn Appender>>();
        assert_sync::<Box<dyn Appender>>();
    }

    // ========================================
    // AC-4.1.1-4.1.3: 验证方法签名正确
    // ========================================

    /// 测试用 Mock Appender
    struct MockAppender {
        events: Mutex<Vec<String>>,
        fail_on_write: bool,
    }

    impl MockAppender {
        fn new() -> Self {
            Self {
                events: Mutex::new(Vec::new()),
                fail_on_write: false,
            }
        }

        fn failing() -> Self {
            Self {
                events: Mutex::new(Vec::new()),
                fail_on_write: true,
            }
        }

        fn event_count(&self) -> usize {
            self.events.lock().map(|g| g.len()).unwrap_or(0)
        }
    }

    impl Appender for MockAppender {
        fn write(&self, event: &LogEvent) -> Result<(), Log4rError> {
            if self.fail_on_write {
                return Err(Log4rError::appender("MockAppender", "模拟写入失败"));
            }

            self.events
                .lock()
                .map_err(|_| Log4rError::appender("MockAppender", "获取锁失败"))?
                .push(format!("[{}] {}", event.level, event.message));
            Ok(())
        }

        fn flush(&self) -> Result<(), Log4rError> {
            Ok(())
        }

        fn close(&self) -> Result<(), Log4rError> {
            Ok(())
        }
    }

    /// UT-4.1-004: 验证 write 方法签名正确
    #[test]
    fn test_write_method_signature() {
        // GIVEN: MockAppender 和 LogEvent
        let appender = MockAppender::new();
        let event = LogEvent::new(crate::level::Level::Info, "test", "测试消息");

        // WHEN: 调用 write 方法
        let result = appender.write(&event);

        // THEN: 返回 Result<(), Log4rError>
        assert!(result.is_ok());
        assert_eq!(appender.event_count(), 1);
    }

    /// UT-4.1-005: 验证 flush 方法签名正确
    #[test]
    fn test_flush_method_signature() {
        // GIVEN: MockAppender
        let appender = MockAppender::new();

        // WHEN: 调用 flush 方法
        let result: Result<(), Log4rError> = appender.flush();

        // THEN: 返回 Result<(), Log4rError>
        assert!(result.is_ok());
    }

    /// UT-4.1-006: 验证 close 方法签名正确
    #[test]
    fn test_close_method_signature() {
        // GIVEN: MockAppender
        let appender = MockAppender::new();

        // WHEN: 调用 close 方法
        let result: Result<(), Log4rError> = appender.close();

        // THEN: 返回 Result<(), Log4rError>
        assert!(result.is_ok());
    }

    /// UT-4.1-007: 验证 write 方法可以返回错误
    #[test]
    fn test_write_can_return_error() {
        // GIVEN: 会失败的 MockAppender
        let appender = MockAppender::failing();
        let event = LogEvent::new(crate::level::Level::Error, "test", "错误消息");

        // WHEN: 调用 write 方法
        let result = appender.write(&event);

        // THEN: 返回 AppenderError
        assert!(result.is_err());
        assert!(matches!(result, Err(Log4rError::AppenderError { .. })));
    }

    /// UT-4.1-008: 验证 LogEvent 可以被 Appender 使用
    #[test]
    fn test_logevent_can_be_used_by_appender() {
        // GIVEN: 各种级别的 LogEvent
        let appender = MockAppender::new();
        let levels = [
            crate::level::Level::Trace,
            crate::level::Level::Debug,
            crate::level::Level::Info,
            crate::level::Level::Warn,
            crate::level::Level::Error,
            crate::level::Level::Fatal,
        ];

        // WHEN: 写入所有级别的事件
        for level in levels {
            let event = LogEvent::new(level, "test", format!("{:?} 消息", level));
            let result = appender.write(&event);
            // THEN: 全部成功
            assert!(result.is_ok());
        }

        assert_eq!(appender.event_count(), 6);
    }
}
